package com.pdool.room.akka;

import akka.actor.AbstractActor;
import cn.hutool.core.exceptions.ExceptionUtil;
import com.pdool.common.constants.Constant;
import com.pdool.common.constants.ErrorCode;
import com.pdool.common.constants.MsgId;
import com.pdool.common.dict.BasePropVo;
import com.pdool.common.dict.CardInfoConfigVo;
import com.pdool.common.dto.room.ClientRoomMsg;
import com.pdool.common.dto.room.CreateRoomInfo;
import com.pdool.common.dto.room.RoleFightInitInfo;
import com.pdool.common.exception.ErrorException;
import com.pdool.common.msg.common.ErrorMsgResp;
import com.pdool.room.context.RoleFightInfo;
import com.pdool.room.context.RoomContext;
import com.pdool.room.controller.TestCom;
import com.pdool.room.core.MsgHandlerItem;
import com.pdool.room.core.MsgMap;
import com.pdool.room.dict.BasePropConfig;
import com.pdool.room.dict.CardConfig;
import com.pdool.room.dict.CardEffectConfig;
import com.pdool.room.enums.RoomState;
import com.pdool.room.fight.FightUtil;
import com.pdool.room.fight.area.FightAreaInfo;
import com.pdool.room.fight.area.HandAreaInfo;
import com.pdool.room.fight.effect.CardFightVo;
import com.pdool.room.mgr.RoomMgr;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 房间actor
 */
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Slf4j
public class RoomActor extends AbstractActor {
    @Autowired
    TestCom testCom;
    @Autowired
    MsgMap msgMap;
    @Autowired
    CardConfig cardConfig;
    @Autowired
    CardEffectConfig cardEffectConfig;
    @Autowired
    BasePropConfig basePropConfig;

    final RoomContext roomContext;

    public RoomActor() {
        roomContext = new RoomContext();
        log.info("---------------> create actor  path  {} ", this.self().path().toString());
    }

    @Override
    public void postStop() throws Exception {
        super.postStop();
        log.error(" roomId  {}   stop",roomContext.getRoomId());
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .match(String.class, t -> {
                    if (roomContext != null && roomContext.getState() == RoomState.READY) {
                        roomContext.decSec();
                    }
                })
                .match(CreateRoomInfo.class, c -> {
                    initRoom(c);
                })
                .match(ClientRoomMsg.class, this::handlerRoomMsg)
                .matchAny(o -> log.error("", o)).build();
    }

    private void handlerRoomMsg(ClientRoomMsg c) {
//        log.info("---------------> 收到消息  {} ,path  {} ", c.getMsgId(), this.self().path().toString());
        try {
            MsgHandlerItem msgMethod = msgMap.getMsgMethod(c.getMsgId());
            Object o = msgMethod.getIn().parseFrom(c.getMsg());
            try {
                msgMethod.getHandler().handle(roomContext,c.getRoleId(),o);
            } catch (ErrorException e) {
                log.error("", e);
                String errorMsg = e.getMessage();
                String errorCode = e.getErrorCode();
                ErrorMsgResp build = ErrorMsgResp.newBuilder().setErrCode(errorCode).setMsg(errorMsg).build();
                RoomMgr.getInstance().sendMsg2Client(c.getRoleId(), MsgId.ERROR, build);
            }
        } catch (Exception e) {
            log.error("", e);
            String s = ExceptionUtil.stacktraceToOneLineString(e);
            ErrorMsgResp build = ErrorMsgResp.newBuilder().setErrCode(ErrorCode.UNKNOWN_ERROR).setMsg(s).build();

            RoomMgr.getInstance().sendMsg2Client(c.getRoleId(), MsgId.ERROR, build);
        }
    }


    private void initRoom(CreateRoomInfo c) {
        log.error("---------------> 创建房间,path  {} ", this.self().path().toString());
        try {
            BasePropVo byKey2 = basePropConfig.getByKey(Constant.PROP_AUTO_PUT_CARD_SEC);
            int maxSec = Integer.parseInt(byKey2.getValue());
            int maxRound = Integer.parseInt(basePropConfig.getByKey(Constant.PROP_MAX_ROUND).getValue());
            //  初始化房间
            roomContext.initRoomContext(c, maxSec, maxRound);
            roomContext.setRoomId(c.getRoomId());
            List<Integer> areaInfoList = c.getAreaInfo();
            List<RoleFightInitInfo> fightInfoList = c.getFightInfoList();
            for (int i = 0; i < fightInfoList.size(); i++) {
                RoleFightInitInfo roleFightInitInfo = fightInfoList.get(i);
                RoleFightInfo roleFightInfo = new RoleFightInfo();
                roleFightInfo.setRoomId(roomContext.getRoomId());
                roleFightInfo.setRoleId(roleFightInitInfo.getRoleId());
                Collections.shuffle(roleFightInitInfo.getCardList());
                makeCardInfo(roleFightInitInfo, i, roleFightInfo);

                //  到时候可以根据配置设置阵营
                roleFightInfo.setPos(roleFightInitInfo.getPos());
                for (int i1 = 0; i1 < areaInfoList.size(); i1++) {
                    FightAreaInfo areaInfo = new FightAreaInfo(roleFightInitInfo.getRoleId(), i1);
                    roleFightInfo.getAreaInfoList().add(areaInfo);
                }
                roomContext.getMemberMap().put(roleFightInitInfo.getRoleId(), roleFightInfo);
                if (roleFightInitInfo.getRoleId() <0){
                    roomContext.readyFight(roleFightInitInfo.getPos());
                }
            }

            roomContext.setCurRound(0);
            roomContext.setState(RoomState.INIT);
        } catch (Exception e) {
            log.error("", e);
        }
    }

    private void makeCardInfo(RoleFightInitInfo roleFightInitInfo, int pos, RoleFightInfo roleFightInfo) {
        int initHandCardCount = Integer.parseInt(basePropConfig.getByKey(Constant.PROP_INIT_HAND_CARD_COUNT).getValue());

        List<Integer> cardList = roleFightInitInfo.getCardList();
        List<CardFightVo> resultList = Lists.newArrayList();
        List<CardFightVo> addHandCardList = new ArrayList<>();
//        cardList.remove((Integer) 25);
//        cardList.remove((Integer) 4);
//        cardList.add(0,25);
//        cardList.add(0,4);
        for (int i = 0; i < cardList.size(); i++) {
            Integer cardId = cardList.get(i);
            CardInfoConfigVo config = cardConfig.getByKey(cardId);
            CardFightVo cardFightVo = new CardFightVo();
            cardFightVo.setRoleId(roleFightInitInfo.getRoleId());
            cardFightVo.setCardId(cardId);
            cardFightVo.setFight(config.getFight(),null,false);
            cardFightVo.setCost(config.getCost());
            cardFightVo.setCardType(config.getCardType());
            cardFightVo.setPos(pos);
            if (i < initHandCardCount) {
                addHandCardList.add(cardFightVo);
            }
            resultList.add(cardFightVo);
        }

        HandAreaInfo handAreaInfo = new HandAreaInfo(roleFightInfo.getRoleId(), -1);
        handAreaInfo.setCardList(addHandCardList);
        roleFightInfo.setHandAreaInfo(handAreaInfo);
        roleFightInfo.setCardList(resultList);

        FightUtil.getInstance().pushHandCardChange(roleFightInitInfo.getRoleId(), addHandCardList);
    }
}